<?php

namespace App\Http\Controllers\Admin;

use App\Models\AdminMenu;
use App\Helpers\Common;

use Illuminate\Http\Request;
use Illuminate\Routing\Controller as Base;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Exception;

/**
 * @author chenh
 */
class BaseController extends Base
{
    protected $admin = '';
    protected $menu = null;
    protected $model = '';
    protected $route = '';
    protected $access = [];

    protected $indexView = 'index'; // Index View
    protected $addView = 'add'; // Add View
    protected $editView = 'edit'; // Edit View
    protected $defaultWhere = [];
    //protected $defaultOrder = [['filed' => 'created_at', 'order' => 'asc']];

    /**
     * 构造函数
     */
    public function __construct()
    {
        //
    }

    /**
     * Init
     */
    public function initialize(Request $request)
    {
        $admin = Auth::guard('admin')->user();
        if (!$admin) {
            return redirect('login');
        }
        $this->admin = $admin;

        $route = explode('/', $request->route()->Uri());
        $this->route = implode('/', $route);
        if (count($route) > 1) {
            $this->menu = AdminMenu::where('app', $route[0])->where('route', $route[1])->first();
            if ($this->menu) {
                $this->model = $this->menu->controller;
            }
        }

        //view()->share('adminInfo', $this->admin);
        view()->share('model', 'admin/' . $this->model);
        //view()->share('route', $route);

        $this->authCheck($request);
    }

    /*
     * 检查路由权限
     */
    private function authCheck(Request $request)
    {
        if ($this->admin->type == 1) {
            // 超级管理员拥有所有权限
            return;
        }
        // 首页  默认有权限
        if (in_array(strtolower($this->route), ['admin/dashboard'])) {
            return true;
        }

        // 用户权限
        $roleIds = \App\Models\AdminRoleUser::where('admin_id', $this->admin->id)->pluck('role_id')->toArray();
        $access = \App\Models\AdminRole::whereIn('id', $roleIds)->pluck('access')->toArray();
        $this->access = implode(',', $access);
        $this->access = explode(',', $this->access);
        if ($this->menu && !in_array($this->menu->id, $this->access)) {
            if ($request->isMethod('post')) {
                return response()->json([
                    'code' => 0,
                    'msg' => '您没有权限！'
                ]);
            }
            abort(403, '您没有权限访问！');
        }
    }

    /**
     * 初始化菜单
     */
    public function initMenu(Request $request)
    {
        $menus = $this->menuCache();
        if (!$menus ) {
            return '';
        }
        $subMenu = function ($menus, $level = 0) use (&$subMenu) {
            $output = '';
            foreach ($menus as $menu) {
                // route access check
                if ($this->admin->type != 1 && !in_array($menu['id'], $this->access) && !in_array(strtolower($menu['route']), ['admin/dashboard'])) {
                    continue;
                }

                if ($level == 0) {
                    $icon = $menu['icon'];

                    $active = '';
                    if ($menu['route'] == 'dashboard') {
                        $active = 'layui-this';
                    }
                    if (empty($menu['items'])) {
                        $url = '';
                        $menu['route'] && $url = url($menu['app'] . '/' . $menu['route']);
                        $output .= '<li class="layui-nav-item ' . $active . '" data-name="' . $menu['name'] . '">';
                        $output .= '<a lay-href="' . $url . '" lay-tips="' . $menu['name'] . '" target="' . $menu['target'] . '">';
                        $output .= '<i class="layui-icon ' . $icon . '"></i>';
                        $output .= '<cite>' . $menu['name'] . '</cite>';
                        $output .= '</a>';
                        $output .= '</li>';
                    } else {
                        $output .= '<li class="layui-nav-item" data-name="' . $menu['name'] . '">';
                        $output .= '<a href="javascript:;" lay-tips="' . $menu['name'] . '">';
                        $output .= '<i class="layui-icon ' . $icon . '"></i>';
                        $output .= '<cite>' . $menu['name'] . '</cite>';
                        $output .= '</a>';
                        $output .= '<dl class="layui-nav-child">';
                        $output .= $subMenu($menu['items'], $level + 1);
                        $output .= '</dl>';
                        $output .= '</li>';
                    }
                } else {
                    if (empty($menu['items'])) {
                        $url = '';
                        $menu['route'] && $url = url($menu['app'] . '/' . $menu['route']);
                        $output .= '<dd class="">';
                        $output .= '<a lay-href="' . $url . '" target="' . $menu['target'] . '">';
                        $output .= $menu['name'];
                        $output .= '</a>';
                        $output .= '</dd>';
                    } else {
                        $output .= '<dd class=" " data-name="' . $menu['name'] . '">';
                        $output .= '<a href="javascript:;" lay-tips="' . $menu['name'] . '">';
                        $output .= $menu['name'];
                        $output .= '</a>';
                        $output .= '<dl class="layui-nav-child">';
                        $output .= $subMenu($menu['items'], $level + 1);
                        $output .= '</dl>';
                        $output .= '</dd>';
                    }
                }
            }
            return $output;
        };
        $output = $subMenu($menus);

        return $output;
    }

    // Cache menu
    private function menuCache()
    {
        $menus = Cache::get('admin_menu');
        if (!$menus) {
            $menus = AdminMenu::getTree(0);
            // 缓存
            //Cache::tags(['admin'])->put('admin_menu', $menus, 3600 * 6);
            Cache::put('admin_menu', $menus, 3600 * 6);
        }

        return $menus;
    }

    /**
     * List
     */
    public function index(Request $request)
    {
        $params = $request->all();

        if ($request->ajax()) {
            $className = '\\App\\Models\\' . $this->model;
            $model = new $className;

            // 每页起始条数
            $start = ($params['page'] - 1) * $params['limit'];
            // 每页显示条数
            $length = $params['limit'];
            // 排序条件
            $order_by = 'created_at';
            $order_sort = 'desc';
            $where = $this->getFilterWhere($request);
            if ($this->defaultWhere) {
                $where = array_merge($this->defaultWhere, $where);
            }

            $query = $model->query();
            foreach ($where as $value) {
                $query->where($value[0], $value[1], $value[2]);
            }
            $count = $query->count();
            $data = $query->orderBy($order_by, $order_sort)->take($length)->skip($start)->get()->toArray();

            if ($data) {
                // 处理列表数据
                $data = $this->handleListData($data);
            }

            $result = [
                'code' => '0',
                'msg' => '',
                'data' => $data,
                'count' => $count,
            ];

            return response()->json($result);
        }

        return view('admin/' . strtolower($this->model) . '/' . $this->indexView, [
            'params' => $params
        ]);
    }

    /**
     * Add
     */
    public function add(Request $request)
    {
        if ($request->isMethod('post')) {
            return $this->savePost($request);
        }

        return view('admin/' . strtolower($this->model) . '/' . $this->addView);
    }

    /**
     * Edit
     */
    public function edit(Request $request, $id)
    {
        if ($request->isMethod('post')) {
            return $this->savePost($request);
        }

        $className = '\\App\\Models\\' . $this->model;
        $model = new $className;

        $info = $model->find($id);
        $info = $model->formatItem($info);

        return view('admin/' . strtolower($this->model) . '/' . $this->editView, [
            'info' => $info
        ]);
    }

    /**
     * Save Post
     */
    protected function savePost($request)
    {
        $className = '\\App\\Models\\' . $this->model;
        $model = new $className;

        if (!$request->post()) {
            return response()->json([
                'code' => 0,
                'msg' => '请求方式不正确'
            ]);
        }

        DB::beginTransaction();
        try {
            $data = self::evalData($request);

            if ($data['id']) {
                // Update
                $data['updated_at'] = time();
                $result = $model->where('id', $data['id'])->update($data);

                $msg = '保存成功!';
                $logInfo = $this->admin->name . '更新了一条' . __($this->model) . '数据。';
            } else {
                // Insert
                $data['created_id'] = $data['updated_id'] = $this->admin->id;
                $data['created_at'] = $data['updated_at'] = time();
                $result = $model->create($data);

                $msg = '添加成功!';
                $logInfo = $this->admin->name . '添加了一条' . __($this->model) . '数据。';
            }

            if ($result === false) {
                DB::rollBack();
                return response()->json([
                    'code' => 0,
                    'msg' => $msg
                ]);
            }

            // 写入日志
            Common::adminLog($request, $logInfo);

            DB::commit();
            return response()->json([
                'code' => 1,
                'msg' => $msg
            ]);
        } catch (Exception $e) {
            DB::rollBack();
            return response()->json([
                'code' => 0,
                'msg' => $e->getMessage()
            ]);
        }
    }

    /**
     * Delete
     */
    public function delete(Request $request, $id)
    {
        $className = '\\App\\Models\\' . $this->model;
        $model = new $className;

        $result = $model->where('id', $id)->delete();
        if ($result === false) {
            return response()->json([
                'code' => 0,
                'msg' => '删除失败'
            ]);
        }

        // 写入日志
        $logInfo = $this->admin->name . '删除了一条' . __($this->model) . '数据。';
        Common::adminLog($request, $logInfo);

        return response()->json([
            'code' => 1,
            'msg' => '删除成功!'
        ]);
    }

    /**
     * 处理表单数据
     */
    protected function evalData($request)
    {
        $data = $request->all();

        // TODO 验证数据

        // 去掉_token、文件上传字段file
        unset($data['_token'], $data['s'], $data['file']);

        return $data;
    }

    /**
     * 处理列表数据
     */
    protected function handleListData($data)
    {
        return $data;
    }

    /**
     * 筛选条件
     */
    protected function getFilterWhere($request)
    {
        $where = [];

        return $where;
    }

    /**
     * 默认条件
     */
    protected function getDefaultWhere()
    {
        $defaultWhere = [
            //['status', '<>', 90] // model 全局的查询范围
        ];

        return $defaultWhere;
    }
}
